#include //*** Enables OTA programming. 1 of 3 lines WiFiServer server(80); //Used for WiFi Server #include #include #include //Real Time Clock library on I2C for DS3231. pin D1 is SCL, pin D2 is SDA #include //Used for DS18B20 temp sensors https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf #include //Used for DS18B20 temp sensors. Run Simple DS18B20 from DallasTemperature first to find sensor addresses. //Run Example Simple.pde from DallasTemperature first to find sensor addresses. #include //I2C library Used for Real Time Clock and MCP23017 I/O expander. Same two wires. #include //RTC library #define ONE_WIRE_BUS D5 //Define pin the one wire bus is on RtcDS3231 Rtc(Wire); // Real Time clock int yvalue, rvalue, input4, analoginput, counter, wkday, offtimewh; // int automode; // auto mode //****ESP Now Receive Variables*************************** // Structure example to receive data // Must match the sender structure typedef struct struct_message { char a[32]; int b; float c; String d; bool e; } struct_message; // Create a struct_message called myData struct_message myData; // Callback function that will be executed when data is received void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) { memcpy(&myData, incomingData, sizeof(myData)); } //****End of ESP Now Receive Variables******************** int lastSecond = -1; // set last second to impossible number so it prints right away then every second int lastSecond1 = -1; // used to reset alert only once per second int currentmillis = 0; int previousmillis = 0; String request, timedate, Month, Day, Hour, Minute, Second, dow, distancestring; String insidetemp, humidity, furnaceLED, basementtemp, outsidetemp, tempdata; float temp1, t2, temp2, h1, prevh1, prevt1, amps; // Furnace Variables int Light = 0; int Fan = 0; float degreesC, temp1raw, temp2raw; int light_level, furnaceONvalue; int seconds, timeNOW, timeLAst; // Ultrasonic variables // int trig = D4;// common trigger output int ultrasonics_read; int distance_echo = D0; int distance_duration; int Barreldistance; int distance=100; int Barrel_full; // initialize level to 100% so pumps don't start after upload - only reads level every minute int Tankduration; int Tankdistance; int Tank_level=100; // initialize level to 100% so pumps don't start after upload - only reads level every minute // End of Ultrasonic Variables OneWire oneWire(ONE_WIRE_BUS); //Used for DS18B20 temp sensors DallasTemperature sensors(&oneWire); //Used for DS18B20 temp sensors DeviceAddress Sens1, Sens2; //Used for DS18B20 temp sensors void setup() { ArduinoOTA.begin(); //*** Enables OTA programming. 2 of 3 lines server.begin(); pinMode(D0, INPUT); // Initialize D1 pin as an input Barrel Ultrasonic echo on Nodemcu 12E board // pinMode(D3, OUTPUT); // Initialize D3 pin as an output Ultrasonic trigger on Nodemcu 12E board pinMode(D4, OUTPUT); // Initialize D4 pin as an output Ultrasonic trigger on Nodemcu 12E board pinMode(D6, OUTPUT); // Initialize D6 pin as an output for LIGHT on relay 1 on Nodemcu 12E board pinMode(D7, OUTPUT); // Initialize D7 pin as an output for FAN on relay 2 on Nodemcu 12E board // Initialize relay outputs to HIGH since LOW activates the relay digitalWrite(D6, HIGH); // Relay 1 for Light digitalWrite(D7, HIGH); // Relay 2 for Fan Rtc.Begin(); //Starts I2C // Start up the DS18B20 library and set temp resolution 11 bits equals .125C sensors.begin(); sensors.getAddress(Sens1, 0); sensors.setResolution(Sens1, 11); sensors.getAddress(Sens2, 1); sensors.setResolution(Sens2, 11); // Uncomment next two lines to set Real Time Clock if required - after setting clock make sure and upload commented version again or time will be reset on reboot // RtcDateTime t = RtcDateTime(19, 9, 12, 14, 8, 0); //set date and time NO leading zeroes (yr mo day Hour min sec) // Rtc.SetDateTime(t); //configure the RTC with object // send about 25 secs before actual time.gov time to allow for compile //******ESP NOW Setup**************************************************** // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // Init ESP-NOW if (esp_now_init() != 0) { // Serial.println("Error initializing ESP-NOW"); return; } // Once ESPNow is successfully Init, we will register for recv CB to // get recv packer info esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); esp_now_register_recv_cb(OnDataRecv); //******End of ESP NOW Setup********************************************* } int automode = 0; // default mode is AUTO OFF mode void loop() { ArduinoOTA.handle(); //*** Enables OTA programming. 3 of 3 lines if (myData.b > 300) digitalWrite(D4, LOW); // Turn the LED on (Note that LOW is the voltage level if (myData.b < 300) digitalWrite(D4, HIGH); // mData.b is coming from the sending NodeMCU //*************Analog Input read****************************************************** analoginput = analogRead(0); //Check!! Nodemcu 12E is digital 0 to 1024 for input 0 to 3.3V NOT 0 to 1.0V on pin A0. furnaceONvalue = analoginput; // furnace program uses this variable for analog input of furnace LED ON //*************End Analog Input read****************************************************** //*******Get Date and Time************************************************* RtcDateTime t = Rtc.GetDateTime(); //get the time from the RTC char str[15]; //declare a string as an array of chars sprintf(str, "%d/%d/%d %d:%d:%d", //%d allows to print an integer to the string t.Year(), //get year method t.Month(), //get month method t.Day(), //get day method t.Hour(), //get Hour method t.Minute(), //get Minute method t.Second() //get Second method ); //********End Get Date and Time*********************************************** //*********Light ON/OFF Logic************************************************* if (Light == 1) digitalWrite(D6, LOW);// Light is on NC contacts so Default is OFF. LOW activates relay to turn Fan ON if (Light == 0) digitalWrite(D6, HIGH);// LOW deactivates relay to turn Light OFF //********End Light ON/OFF Logic********************************************* //********* Fan ON/OFF Logic************************************************* if (Fan == 1) { digitalWrite(D7, LOW); // Turn ON Fan } if (Fan == 0) { digitalWrite(D7, HIGH); // Turn OFF Fan } //*********Fan ON/OFF Logic************************************************* //********Read temp from DS18B20s***************************** sensors.requestTemperatures(); // Send the command to get temperatures from DS18B20s // Reading temperatures from sensors temp1raw = sensors.getTempCByIndex(0); //DSB1820 temp1 if ((temp1raw > -50.0) && (temp1raw < 50.0)) temp1 = temp1raw; // error checking temp2raw = sensors.getTempCByIndex(1); //DSB1820 temp2 if ((temp2raw > -50.0) && (temp2raw < 50.0)) temp2 = temp2raw; // error checking if ((automode == 1) && (temp1 > 24.0)) digitalWrite(D7, LOW); //LOW activates relay if ((automode == 1) && (temp1 < 23.0)) digitalWrite(D7, HIGH); // HIGH deactivates relay if ((automode == 1) && (temp1 > 24.0)) Fan = 1; // for web page display if ((automode == 1) && (temp1 < 23.0)) Fan = 0; // for web page display //********End read temperature **************************************** //*****Read Ultrasonics********************************************************* if ((t.Second() == 0) || (t.Second() == 5) || (t.Second() == 10) || (t.Second() == 15) || (t.Second() == 30) || (t.Second() == 35) || (t.Second() == 40) || (t.Second() == 45) || (t.Second() == 50) || (t.Second() == 55)) ultrasonics_read = 0; // reset ultrasonics_read bit after 0 if (ultrasonics_read == 0){ // only read ultrasonics once every 5 secs ultrasonics_read = 1; // only read once every five seconds // Ultrasonic Distance Sensor delay(10); // Clears the trig // digitalWrite(trig, LOW); delayMicroseconds(2); // Sets the trigPin on HIGH state for 10 micro seconds // digitalWrite(trig, HIGH); delayMicroseconds(10); // digitalWrite(trig, LOW); // Reads the echoPin, returns the sound wave travel time in microseconds distance_duration = pulseIn(distance_echo, HIGH); // Calculating the distance distance = distance_duration*0.17; // BML demo for distance in mm delay(100); } //*****End Read Ultrasonic***************************************************** //***read photoresistor light_level ***** light_level = 1024 - analogRead(0); if ((automode == 1) && (light_level < 500)) Light = 1; if ((automode == 1) && (light_level > 600)) Light = 0; //********end read photoresistor light_level ******************* //*******WiFi detect client and record input******************************** // Check if a client has connected WiFiClient client = server.available(); if (!client) { return; } // Read the first line of the request request = client.readStringUntil('\r'); client.flush(); //*******End of WiFi detect client and record input******************************** //*************Actions on web page button click. Buttons defined below.************************ if (request.indexOf("/FAN=ON") != -1) {// Input from screen. No spaces in name. if (automode == 0) Fan = 1; } if (request.indexOf("/FAN=OFF") != -1) {// Input from screen. No spaces in name. if (automode == 0) Fan = 0; } // Match the request if (request.indexOf("/LIGHT=ON") != -1) {// yvalue = Sys ON. Input from screen. No spaces in name. if (automode == 0) Light = 1; } if (request.indexOf("/LIGHT=OFF") != -1) {// Input from screen. No spaces in name. if (automode == 0) Light = 0; } if (request.indexOf("/AUTO_ON") != -1) {// Input from screen. No spaces in name. Water heater auto mode automode = 1; } if (request.indexOf("/AUTO_OFF") != -1) {// Input from screen. No spaces in name. Water heater auto mode automode = 0; } request.indexOf("/HOME"); // Go to Home page after LEDs set. //*******End of web page button actions****************************************************** //****** Return the response in HTML on web page************************************ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); // do not forget this one client.println(""); client.println( // start code html with this. Have to add quotes before and after. Delete most html quotes in line. "" "" "ESP NOW Web Page Demo" // "" // Auto refresh every 60 secs. Issues? "" "" "" "" //Use monospace font to make columns of text and numbers line up "

"); // large font applies between

and

below //*********End HTML page start of defintion***************************************** //*********Print Date and Time add leading zeroes to Web Page*********************************** Hour = String(t.Hour()); // integers like t.Hour() are used for comparisons and control. Change to string for display and add leading zeroes if (t.Hour() <= 9) Hour = "0" + Hour; // adjust for 0-9 Minute = String(t.Minute()); if (t.Minute() <= 9) Minute = "0" + Minute; // adjust for 0-9 Second = String(t.Second()); if (t.Second() <= 9) Second = "0" + Second; // adjust for 0-9 if (t.DayOfWeek() == 0) dow = " Sun"; // t.DayOfWeek() calculated from rest of date not from DS3231 if (t.DayOfWeek() == 1) dow = " Mon"; if (t.DayOfWeek() == 2) dow = " Tue"; if (t.DayOfWeek() == 3) dow = " Wed"; if (t.DayOfWeek() == 4) dow = " Thu"; if (t.DayOfWeek() == 5) dow = " Fri"; if (t.DayOfWeek() == 6) dow = " Sat"; Month = String(t.Month()); Day = String(t.Day()); if (t.Month() <= 9) Month = "0" + Month; // adjust for 0-9 in month if (t.Day() <= 9) Day = "0" + Day; // adjust for 0-9 in day timedate = String(t.Year())+ "/" + Month + "/" + Day + " " + Hour + ":" + Minute + ":" + Second ; // create string for display with one client.println client.println(timedate); client.println(" "); // add spaces client.println(dow); // print day of week client.println(" "); // add spaces //*********End Print Date and Time to Web Page ******************************************** //*********Web Page Button Style defintion CSS****************************************************************** client.println( //html output. Put quotes around html code. Don't have to client.println every line "" //*****End Web Page Button Style Definition************************************************************************************************ //******Web Page Buttons Definitions************************************************************************************************ "
" "" // LIGHT ON button definition. No spaces " " // horizontal space between buttons "" //LIGHT OFF button definition. No spaces " " "" // FAN ON button definition. No spaces " " // horizontal space between buttons "" //FAN OFF button definition. No spaces " " // horizontal space between buttons ""); //Home button definition. No spaces // client.print("   "); // add spaces //client.println( // "      "); // add spaces //*****End Button Definition************************************************************************************************ //***** Display data to web page client.println("" //Use monospace font to make columns of text and numbers line up "

"); // large font applies between

and

below tempdata = "Temp "+String(temp1,1)+"C"; client.println(tempdata); client.println(" "); client.println(" Light_Level "); client.println(myData.b); client.println(" "); distancestring = "Distance "+String(distance)+"mm"; // client.println(distancestring); client.println(" Counter "); client.println(myData.c); client.println(" "); client.println("
"); client.println("
"); client.println("    "); // client.println(" "); //client.println(" "); client.println( //***Furnace and water heater buttons*************** " " //Clear Flag button definition. No spaces "        " " "); //***End furnace and water heater buttons*********** // "
"); //****Print data to web page client.println("" //Use monospace font to make columns of text and numbers line up "

"); // large font applies between

and

below client.println(" "); client.println("           "); if (automode == 1) client.println("Auto:ON_"); if (automode == 0) client.println("Auto:OFF"); client.println(" "); client.println(" "); if (Light == 0) client.println("Light:OFF"); if (Light == 1) client.println("Light:ON_"); client.println(" "); if (Fan == 0) client.println("Fan:OFF"); if (Fan == 1) client.println("Fan:ON_"); client.println("       "); client.println("ESP NOW"); client.println("
"); client.println("           "); client.println("
"); client.println("
"); client.println("
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "."); // add period below the background you want to display or it won't scroll past last text client.println("

" ""); client.println("
"); delay(1); client.println(""); delay(200); client.stop(); // disconnect client to allow other clients delay(1);